#pragma once

#include <algorithm>
#include <unordered_map>
#include <utility>

#include "src/hash_point.h"
#include "src/point.h"
#include "src/utils.h"

namespace pathfind {

class Graph {

public:
  typedef std::unordered_map<IntPoint, int> Map;
  typedef Map::iterator MapIterator;
  typedef Map::const_iterator ConstMapIterator;

public:
  explicit Graph(std::unordered_map<IntPoint, int> &, int, int);

  float heuristic(const IntPoint &from, const IntPoint &to,
                  const IntPoint &goal) const;
  float cost(const IntPoint &from, const IntPoint &to,
             const IntPoint &goal) const;

  std::unordered_map<IntPoint, float> get_neighbours(const IntPoint &p);
  DIRECTION get_direction(IntPoint &from, IntPoint &to) const;

  bool is_position_out_of_range(const IntPoint &) const;
  bool is_position_valid(const IntPoint &) const;

  int32_t get_weight(const IntPoint &) const;

private:
  void add_neighbour(const IntPoint &);

private:
  Map map_;
  std::unordered_map<IntPoint, float> neighbours_;

  int width_;
  int height_;

  MapIterator map_iterator_;
  ConstMapIterator const_map_iterator_;
};
}
